package com.gusti.turnos.services.impl;

import java.util.Random;

import javax.servlet.http.HttpSession;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.gusti.turnos.form.LoginForm;
import com.gusti.turnos.model.User;
import com.gusti.turnos.response.views.LoginResponse;
import com.gusti.turnos.services.AbstractService;
import com.gusti.turnos.services.IAuthenticationService;
import com.gusti.turnos.util.MessageUtil;
import com.gusti.turnos.util.ServerUtil;

/**
 * 
 * @author gusti
 *
 */
@Service
public class AuthenticationService extends AbstractService implements IAuthenticationService {

	private static final int TEMPORARY_PASSWORD_LENGTH = 10;
	private static final Random RANDOM_GENERATOR = new Random();

	@Override
	public LoginResponse login( LoginForm loginForm ) {

		LoginResponse loginResponse = new LoginResponse();

		//check parameters
		if( StringUtils.isEmpty( loginForm.getEmail() ) || StringUtils.isEmpty( loginForm.getPassword() ) )	{
			loginResponse.setErrorMessage( MessageUtil.getMessage( MessageUtil.ERROR_INVALID_PARAMETERS ) );
			return loginResponse;
		}

		//check if user exists
		User user = userDao.retrieveUserByStringField( "email", loginForm.getEmail() );
		if( !user.isNew() ) {
			//check the password
			String suppliedDigest = encodePassword( loginForm.getPassword() );
			if( suppliedDigest.equals( user.getPassword() ) ) {
				loginResponse.setSuccess( true );
			} else {
				loginResponse.setErrorMessage( MessageUtil.getMessage( MessageUtil.ERROR_AUTHENTICATION_FAILED ) );
				return loginResponse;
			}
		} else {
			loginResponse.setErrorMessage( MessageUtil.getMessage( MessageUtil.ERROR_AUTHENTICATION_FAILED ) );
			return loginResponse;
		}

		if( loginResponse.isSuccess() ) {
			//clean user password
			user.setPassword(null);

			HttpSession httpSession = ServerUtil.getInstance().getSession(true);
			httpSession.setAttribute( ServerUtil.CURRENT_USER, user );

			loginResponse.setUserName( user.getName() );
		}

		return loginResponse;
	}

	@Override
	public void logout() {

		HttpSession httpSession = ServerUtil.getInstance().getSession(false);
		if( httpSession != null ) {
			httpSession.invalidate();
		}
	}

	public static String generateTemporaryPassword() {

		StringBuilder password = new StringBuilder();

		final String possibleCharacters = "0123456789bcdfghjkmnpqrstvwxyz"; 
		boolean[] used = new boolean[possibleCharacters.length()];

		int i = 0; 
		while( i < TEMPORARY_PASSWORD_LENGTH ) { 
			int randomIndex = RANDOM_GENERATOR.nextInt(possibleCharacters.length());
			char randomChar = possibleCharacters.charAt(randomIndex);

			if (!used[randomIndex]) {
				used[randomIndex] = true;
				password.append(randomChar);
				i++;
			}
		}

		return password.toString();
	}

	public static String encodePassword( String password ) {

		return new String( Base64.encodeBase64( DigestUtils.md5( password ) ) );
	}
}
